package gwtappcontainer.server.apps.security;

import static gwtappcontainer.server.apps.security.OfyService.ofy;
import gwtappcontainer.server.DatastoreNamespaces;
import gwtappcontainer.server.apps.APIException;
import gwtappcontainer.shared.apis.APIResponse.Status;
import gwtappcontainer.shared.apps.security.RoleProp;
import gwtappcontainer.shared.apps.security.UserProp;

import java.util.TreeSet;

import com.google.appengine.api.NamespaceManager;


public class PrivilegeRepository {	
	
	private final static String NAMESPACE = DatastoreNamespaces.SECURITY;
	private final static String KEY = "KEY";
	
	public static TreeSet<String> getAllPrivileges() {
				
		TreeSet<String> privileges = new TreeSet<String>();
		
		NamespaceManager.set(NAMESPACE);
		PrivilegeEntity entity = ofy().load().type(PrivilegeEntity.class).id(KEY).get();
		
		if (null == entity)
			return privileges;
		
		privileges = entity.privileges;					
		
		return privileges;
	}
	
	public static void addPrivilege(String privilege, String login) {
		AccessController.ensurePrivilege(login, Privileges.EDIT_PRIVILEGE);
		
		NamespaceManager.set(NAMESPACE);
		privilege = privilege.toUpperCase();
		PrivilegeEntity entity = ofy().load().type(PrivilegeEntity.class).id(KEY).get();
		
		if (entity == null) {
			entity = new PrivilegeEntity();
			entity.id = KEY;
		}
		
		if (entity.privileges.contains(privilege))
			throw new APIException(Status.ERROR_RESOURCE_ALREADY_EXISTS, 
					"Privilege [" + privilege + "] already exists");
		
		entity.privileges.add(privilege);
		ofy().save().entity(entity).now();		
	}
	
	public static void deletePrivilege(String privilege, String login) {			
		
		AccessController.ensurePrivilege(login, Privileges.EDIT_PRIVILEGE);
		
		privilege = privilege.toUpperCase();
		
		NamespaceManager.set(NAMESPACE);
		PrivilegeEntity entity = ofy().load().type(PrivilegeEntity.class).id(KEY).get();		
				
		if (entity == null)
			throw new APIException(Status.ERROR_RESOURCE_DOES_NOT_EXIST, 
					"Privilege [" + privilege + "] does not exist. There are no existing privileges");
		
		if (! entity.privileges.contains(privilege))
			throw new APIException(Status.ERROR_RESOURCE_DOES_NOT_EXIST, 
					"Privilage [" + privilege + "] does not exist");
		
		//ensure no role has this privilege	
		TreeSet<RoleProp> props = RoleRepository.getAllRoles();
		String rolesWithPrivilege = "";
		for (RoleProp roleProp : props) {
			if (roleProp.privileges.contains(privilege))
				rolesWithPrivilege += roleProp.role + ", ";
		}
		
		if (! rolesWithPrivilege.equals(""))
			throw new APIException(Status.ERROR_PRECONDITION_FAILURE, 
					"Privilege [" + privilege + "] is assigned to following roles - [" +
				    rolesWithPrivilege + "]. Please unassign privilege [" + privilege + 
				    "] from these roles first.");
		
		//ensure no user has this privilege
		TreeSet<UserProp> allUsers = UserRepository.getAllUsers();
		String usersWithPrivilege = "";
		for (UserProp userProp : allUsers) {
			if (userProp.privileges.contains(privilege))
				usersWithPrivilege += userProp.email + ", ";
		}
		
		if (! usersWithPrivilege.equals("")) {
			throw new APIException(Status.ERROR_PRECONDITION_FAILURE, 
					"Privilege [" + privilege + "] is assigned to following users - [" +
				    usersWithPrivilege + "]. Please unassign privilege [" + privilege + 
				    "] from these users first.");
		}
				
		entity.privileges.remove(privilege.toUpperCase());
		ofy().save().entity(entity).now();				
	}		
}
